package com.taoye.thread;

import cn.hutool.core.date.DateUtil;

public class Demo36 {
	public static void main(String[] args) throws InterruptedException {
		Demo36User user = new Demo36User();
		user.setUserName("AA-name");
		user.setUserPass("AA-pass");
		Demo36Service service = new Demo36Service(user);
		Thread t = new Demo36ThreadA(service);
		t.setName("A");
		t.start();
		Thread.sleep(500);
		Thread t1 = new Demo36ThreadB(service);
		t1.setName("B");
		t1.start();
	}
}

/**
 * 自定义user对象，用来测试指令重排
 * @author Mr.Tao
 *
 */
class Demo36User {
	private String userName;
	private String userPass;
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserPass() {
		return userPass;
	}
	public void setUserPass(String userPass) {
		this.userPass = userPass;
	}
	
	@Override
	public String toString() {
		return "Demo36User [userName=" + userName + ", userPass=" + userPass + "]";
	}
}


class Demo36Service {
	private Demo36User user;

	public Demo36Service(Demo36User user) {
		this.user = user;
	}

	public void fun() {
		/**
		 * 这里使用自定义对象作为同步代码块的锁
		 */
		synchronized (user) {
			try {
				System.out.println(Thread.currentThread().getName() + "线程执行了fun1，当前时间：" + DateUtil.now());
				//在这里A线程进来的时候，修改了锁定对象的值
				if(Thread.currentThread().getName().equals("A")) {
//					user = new Demo36User(); 如果在这里重新new了user对象，会导致锁失效
					//只改变对象里面的属性，不影响锁
					user.setUserName("BB-name");
					user.setUserPass("BB-pass");
				}
				Thread.sleep(2000);
				System.out.println(Thread.currentThread().getName() + "线程fun1执行结束，当前时间：" + DateUtil.now());
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}

class Demo36ThreadA extends Thread {
	Demo36Service service;

	public Demo36ThreadA(Demo36Service service) {
		this.service = service;
	}

	@Override
	public void run() {
		// 这里调用的不是静态方法
		service.fun();
	}
}

class Demo36ThreadB extends Thread {
	
	Demo36Service service;

	public Demo36ThreadB(Demo36Service service) {
		this.service = service;
	}

	@Override
	public void run() {
		service.fun();
	}
}
